package com.novoda; import android.app.Activity; import android.os.Bundle; import android.util.Log; import android.widget.TextView; import javax.crypto.BadPaddingException; import javax.crypto.Cipher; import javax.crypto.IllegalBlockSizeException; import javax.crypto.NoSuchPaddingException; import javax.crypto.SecretKey; import javax.crypto.SecretKeyFactory; import javax.crypto.spec.PBEParameterSpec; import java.io.UnsupportedEncodingException; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.spec.InvalidKeySpecException; public class Encrypt extends Activity { private static final String SECRET_PASSWORD_TO_ENCRYPT = "secretPassword"; private static final String TAG = "Encrypt"; final String CIPHER_TYPE = "PBEWithMD5AndDES/CBC/PKCS5Padding"; final String ALGORITHM = "PBEWithMD5AndDES"; final String CHARSET = "UTF-8"; /* * Change string for your app. How you secure this key is up to yourself. * I'm all ears as too suggestions for best practices in securing this key within the app programatically. */ final String SECRET_KEY = "some_string"; final byte[] SALT = { (byte) 0x03, (byte) 0x64 }; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); String hash = transform(SECRET_PASSWORD_TO_ENCRYPT, Cipher.ENCRYPT_MODE); ((TextView)findViewById(R.id.txt_encrypted)).setText(hash); ((TextView)findViewById(R.id.txt_unencrypted)).setText(transform(hash, Cipher.DECRYPT_MODE)); } String transform(String var, int transformationType) { String passwordHashed = ""; try { passwordHashed = crypt(transformationType, var); } catch (CryptException e) { if (transformationType == Cipher.ENCRYPT_MODE) { Log.e(TAG, "A problem during the encryption has occurred", e); passwordHashed = ""; } if (transformationType == Cipher.DECRYPT_MODE) { Log.e(TAG, "A problem during the decryption has occurred:", e); } } return passwordHashed; } public String crypt(int mode, String encryption_subject) throws CryptException { final PBEParameterSpec ps = new javax.crypto.spec.PBEParameterSpec(SALT, 20); final SecretKeyFactory kf = getSecretKeyFactory(); final SecretKey k = getSecretKey(kf); final Cipher crypter = getCipherInstance(); String result; switch(mode){ case Cipher.DECRYPT_MODE: initialise(ps, k, crypter, Cipher.DECRYPT_MODE); result = getString(encryption_subject, crypter); break; case Cipher.ENCRYPT_MODE: default: initialise(ps, k, crypter, Cipher.ENCRYPT_MODE); result = encode(encryption_subject, crypter); } return result; } private SecretKeyFactory getSecretKeyFactory() throws CryptException { try { return SecretKeyFactory.getInstance(ALGORITHM); } catch (NoSuchAlgorithmException e) { throw new CryptException(e); } } private SecretKey getSecretKey(SecretKeyFactory kf) throws CryptException { try { return kf.generateSecret(new javax.crypto.spec.PBEKeySpec(SECRET_KEY.toCharArray())); } catch (InvalidKeySpecException e) { throw new CryptException(e); } } private Cipher getCipherInstance() throws CryptException { try { return Cipher.getInstance(CIPHER_TYPE); } catch (NoSuchAlgorithmException | NoSuchPaddingException e) { throw new CryptException(e); } } private void initialise(PBEParameterSpec ps, SecretKey k, Cipher crypter, int decryptMode) throws CryptException { try { crypter.init(decryptMode, k, ps); } catch (InvalidKeyException | InvalidAlgorithmParameterException e) { throw new CryptException(e); } } private String getString(String encryption_subject, Cipher crypter) throws CryptException { try { return new String(finishTransformation(crypter, getDecode(encryption_subject)), CHARSET); } catch (UnsupportedEncodingException e) { throw new CryptException(e); } } private String encode(String encryption_subject, Cipher crypter) throws CryptException { try { return Base64.encode(finishTransformation(crypter, encryption_subject.getBytes(CHARSET))); } catch (UnsupportedEncodingException e) { throw new CryptException(e); } } private byte[] finishTransformation(Cipher crypter, byte[] bytes) throws CryptException { try { return crypter.doFinal(bytes); } catch (IllegalBlockSizeException | BadPaddingException e) { throw new CryptException(e); } } private byte[] getDecode(String encryption_subject) throws CryptException { try { return Base64.decode(encryption_subject); } catch (Base64DecoderException e) { throw new CryptException(e); } } }